﻿// See https://aka.ms/new-console-template for more information

//创建Httphelper对象
using CsharpHttpHelper;
using DeleteExamFromEfilm;
using Microsoft.Extensions.Configuration;
using System.Text;
using System.Security.Cryptography;
using System.Net;
using Newtonsoft.Json;
using System.Data;
using System.Runtime.CompilerServices;
using System.Reflection.Metadata.Ecma335;
using System.Collections;
using System.Collections.Concurrent;
using Org.BouncyCastle.Utilities.IO;
using Org.BouncyCastle.Bcpg.OpenPgp;



//业务逻辑备注
//1、系统根据SQL，查询数据，然后调用接口删除，后台删除文件，并标记为删除状态。
//2、一个线程查询所有delete = 1的记录，并删除所有相关记录表。

HttpHelper http = new HttpHelper();

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.AddJsonFile("application.json", true, true);
var ConfigRoot = builder.Build();//根节点
string serverurl = ConfigRoot["serverurl"];
string sql_where = ConfigRoot["sql_where"];
string token = ConfigRoot["token"];

string postUrl = "";
string postdata = "";

int threadCount = Int32.Parse(ConfigRoot["threadCount"]);


DbHelperMySQL.connectionString = ConfigRoot["mysql"];
log(DbHelperMySQL.connectionString);
ConcurrentQueue<DataRow> queue = new ConcurrentQueue<DataRow>();


log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + @"\log4net.config"));

for (int i = 0; i < threadCount; i++)
{
    Thread thread = new Thread(logicDelExams);
    thread.Start();
}


//删除数据库的线程
Thread thread_deleteDB = new Thread(DeleteDB);
thread_deleteDB.Start();

while (true)
{
    if (queue.Count == 0)
    {
        string sql = string.Format("select * from cloud_examination where ");
        if (sql_where == "")
        {
            log("缺少查询条件！");
            Thread.Sleep(1000 * 60);
            return;
        }
        else
        {
           
            //查找医院列表
            string path = Environment.CurrentDirectory + @"\sitelist.txt";
            string[] txtList = System.IO.File.ReadAllLines(path) ;
            if (txtList.Length !=0)
            {
                sql += " snd_site_id in(";
                string siteIdList = "";
                foreach (string sitename in txtList)
                {
                    string sql_get_siteid = string.Format("select siteid from u_site where siteName = '{0}'", sitename);
                    object obj = DbHelperMySQL.GetSingle(sql_get_siteid);
                    if (obj == null)
                    {
                        log("未找到医院：" + sitename);
                        continue;
                    }
                    else
                    {
                        string siteid = obj.ToString();
                        siteIdList += "'" + siteid + "',";
                    }
                }
                siteIdList = siteIdList.Trim(',');
                
                sql += siteIdList ;
                sql += ")";
            }
            sql = sql + sql_where;
 
        }
        log("sql=" + sql);


        DataTable dt;
        try
        {
            dt = DbHelperMySQL.Query(sql).Tables[0];
            log("加入队列 = " + dt.Rows.Count);
            if (dt.Rows.Count == 0)
            {
                Thread.Sleep(1000 * 5);
                continue;
            }
            else
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    queue.Enqueue(dt.Rows[i]);
                }
            }

        }
        catch (Exception ex)
        {
            log(ex.ToString());
            continue;
        }
    }
 
}


//逻辑删除
void logicDelExams()    
{
    while (true)
    {
        try
        {
            DataRow row;
            if (!queue.TryDequeue(out row))
            {
                Thread.Sleep(1000);
                continue;
            } 

            string exam_id = row["exam_id"].ToString();
            postUrl = serverurl + @"efilm/api/cloud/logicDelExams";

            log("post url = " + postUrl);

            string sign = token + "#" + exam_id;
            sign = GetMd5_32(sign).ToLower().Replace("-", "");
            postdata = string.Format("?examId={0}&token={1}&sign={2}", exam_id, token, sign);
            log("post data = " + postdata);
            HttpHelper httpHelper = new HttpHelper();
            HttpItem item_delete = new HttpItem()
            {
                URL = postUrl + postdata, //POST URL
                Method = "POST",// 可选项 默认为Get   
                ContentType = "application/x-www-form-urlencoded" ,//返回类型    可选项有默认值
                Timeout = 100000,
            };
            if (postUrl.IndexOf("https") > -1)
            {
                item_delete.SecurityProtocol = SecurityProtocolType.Tls;
            }
            item_delete.Header.Add("auth", token);
            string snd_site_id = row["snd_site_id"].ToString();
            string sql_getHospitalName = string.Format("select sitename from u_site where siteid = '{0}'", snd_site_id);
            string siteName = DbHelperMySQL.GetSingle(sql_getHospitalName).ToString();
            log(string.Format("正在逻辑删除，检查时间：{0}，患者姓名：{1}，检查类型：{2}，examid={3},检查医院：{4}", row["study_time"].ToString(), row["patient_name"].ToString(), row["modality"].ToString(), exam_id, siteName));

            var PostResult = httpHelper.GetHtml(item_delete);
            if (PostResult.StatusCode == HttpStatusCode.OK)
            {
                //获取请请求的Html
                string html = PostResult.Html;
                dynamic JsonObj = JsonConvert.DeserializeObject<dynamic>(html);
                if (JsonObj.resultCode == "200")
                {
                    log(html);
                    log("逻辑删除成功");
                }
                else
                {
                    log("逻辑删除失败，原因：" + html);
                }
                Thread.Sleep(100);
            }
            else
            {
                log("调用逻辑删除接口失败=" + PostResult.Html);
                //Thread.Sleep(1000 * 10);
            }
        }
        catch (Exception ex)
        {
            log(ex.ToString());
            Thread.Sleep(1000 * 10);
        }
         
    }
   
}

//删除数据库的线程
void DeleteDB()
{
    while (true)
    {
        string sql = "select * from cloud_examination where deleted = 1 order by create_time asc limit 500";
        LogHelper.Info("sql=" + sql);
        try
        {

            if (DateTime.Now.Hour > 23 || DateTime.Now.Hour < 6)
            {

                DataTable dt = DbHelperMySQL.Query(sql).Tables[0];
                foreach (DataRow row in dt.Rows)
                {
                    string exam_id = row["exam_id"].ToString();

                    List<string> list = new List<string>();
                    list.Add(string.Format("delete from cloud_instance where exam_id = '{0}'", exam_id));
                    list.Add(string.Format("delete from cloud_series where exam_id = '{0}'", exam_id));
                    list.Add(string.Format("delete from cloud_examination where exam_id = '{0}'", exam_id));
                    list.Add(string.Format("delete from cloud_report where exam_id = '{0}'", exam_id));
                    list.Add(string.Format("delete from cloud_exam_method where exam_id = '{0}'", exam_id));

                    DbHelperMySQL.ExecuteSqlTran(list);

                    LogHelper.Info("物理删除数据库成功，exam_id = " + exam_id);
                    Thread.Sleep(2000);
                }
            }
            else
            {
                Thread.Sleep(1000 * 60);
                continue;

            }


            
        }
        catch (Exception ex)
        {
            log(ex.ToString());
        }
    }
}

void log(string msg)
{
    Console.WriteLine(DateTime.Now.ToString() + "  " + "线程【" + Thread.CurrentThread.ManagedThreadId + "】" +  msg);
    LogHelper.Info(msg);
}


/// <summary>
/// MD5 16位加密 加密后密码为大写
/// </summary>
/// <param name="ConvertString"></param>
/// <returns></returns>
static string GetMd5_16(string ConvertString)
{
    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
    string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
    t2 = t2.Replace("-", "");
    return t2;
}

static string GetMd5_32(string ConvertString)
{
    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
    string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)));
    
    return t2;
}

string Base64Code(string Message)
{
    byte[] bytes = Encoding.Default.GetBytes(Message);
    return Convert.ToBase64String(bytes);
}

